<?php

namespace App\Models;

use App\Mailer\UserMailer;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Auth;
use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use Traits\LastActivedAtHelper;
    use Traits\ActiveUserHelper;
    use HasRoles;
    use Notifiable {
        notify as protected laravelNotify;
    }

    public function topics()
    {
        $result = $this->hasMany(Topic::class);
        return $result;
    }

    public function topicsOrderRecent(){
        $result = $this->hasMany(Topic::class)->withOrder('recent');
        return $result;
    }

    public function isAuthorOf($model)
    {
        return $this->id == $model->user_id;
    }

    public function replies()
    {
        return $this->hasMany(Reply::class);
    }

    public function notify($instance)
    {
        // 如果要通知的人是当前用户，就不必通知了！
        if ($this->id == Auth::id()) {
            return;
        }
        $this->increment('notification_count');
        $this->laravelNotify($instance);
    }

    public function markAsRead()
    {
        $this->notification_count = 0;
        $this->save();
        $this->unreadNotifications->markAsRead();
    }

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'introduction', 'avatar', 'confirmation_token',
        'github_id', 'github_name', 'github_url', 'qq_openid',
        'api_token', 'setting',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * $casts 属性数组在模型中提供了将属性转换为常见的数据类型的方法，
     * 且键是那些需要被转换的属性名称，值则是代表字段要转换的类型。
     * 支持的转换的类型有：integer、real、float、double、string、boolean、object、array、collection、date、datetime、timestamp
     */
    protected $casts = [
        'setting' => 'array'// setting 属性以数组被保存在数据库中，把它转换为数组
    ];

    /**
     * 发送邮件
     *
     * @param string $token
     */
    public function sendPasswordResetNotification($token)
    {
        (new UserMailer())->passwordReset($this->email, $token);
    }

    /**
     * 设置用户的信息
     *
     * @return Setting
     */
    public function settings()
    {
        return new Setting($this);
    }

    public function setPasswordAttribute($value)
    {
        // 如果值的长度等于 60，即认为是已经做过加密的情况
        if (strlen($value) != 60) {
            // 不等于 60，做密码加密处理
            $value = bcrypt($value);
        }
        $this->attributes['password'] = $value;
    }

    public function setAvatarAttribute($path)
    {
        // 如果不是 `http` 子串开头，那就是从后台上传的，需要补全 URL
        if ( ! starts_with($path, 'http')) {
            // 拼接完整的 URL
            $path = config('app.url') . "/uploads/images/avatars/$path";
        }
        $this->attributes['avatar'] = $path;
    }
}
